function Snake(context) {
  this.body = [
    { row: 3, col: 4 },
    { row: 3, col: 3 },
    { row: 3, col: 2 },
  ];

  /**
   * 方向
   *    N 0
   * E 3   W 1
   *    S 2
   */
  this.direction = 1;
  this.nextDirection = 1;
}

Snake.prototype.getDirectionString = function () {
  if (this.direction == 0) return 'N';
  else if (this.direction == 1) return 'W';
  else if (this.direction == 2) return 'S';
  else return 'E';
};

// 渲染
Snake.prototype.render = function () {
  //蛇头
  game.setHTML(
    this.body[0].row,
    this.body[0].col,
    `./asset/${this.getDirectionString()}.png`
  );
  for (let i = 1; i < this.body.length; i++) {
    game.setHTML(this.body[i].row, this.body[i].col, './asset/body.png');
  }
};

// 改变蛇的方向
Snake.prototype.changeDirection = function (dir) {
  // 不允许反方向的移动
  if (Math.abs(this.direction - dir) == 2) {
    return;
  }
  this.nextDirection = dir;
};

// 蛇往头的方向移动一格
Snake.prototype.update = function () {
  // 头加一
  switch (this.nextDirection) {
    case 1:
      this.body.unshift({
        row: this.body[0].row,
        col: this.body[0].col + 1,
      });
      break;
    case 3:
      this.body.unshift({
        row: this.body[0].row,
        col: this.body[0].col - 1,
      });
      break;
    case 0:
      this.body.unshift({
        row: this.body[0].row - 1,
        col: this.body[0].col,
      });
      break;
    case 2:
      this.body.unshift({
        row: this.body[0].row + 1,
        col: this.body[0].col,
      });
      break;
  }

  // 死亡判断
  /**
   * 触碰地图边界
   * 碰到自己
   */
  if (isOutOfMap(this.body[0], game) || isCrashSelf(this.body)) {
    game.gameOver();
    return;
  }

  // 碰到食物，吃掉，否则移动
  if (isFood(this.body[0])) {
    // 新生成一个事物
    game.food = new Food(game);
    game.frame = 0;
    game.score += 100;
  } else {
    // 屁股删除
    this.body.pop();
    this.direction = this.nextDirection;
  }
  console.log(this.body.length);
};

function isFood(head) {
  const food = game.food;
  if (head.row == food.row && head.col == food.col) {
    return true;
  }
  return false;
}

function isOutOfMap(head, game) {
  if (
    head.row > game.row - 1 ||
    head.row < 0 ||
    head.col > game.col - 1 ||
    head.col < 0
  ) {
    return true;
  }
  return false;
}

function isCrashSelf(body) {
  const head = body[0];
  for (let i = 1; i < body.length; i++) {
    if (head.row == body[i].row && head.col == body[i].col) {
      return true;
    }
  }
  return false;
}
